﻿using Autofac;
using Catastrophe.AutoSulution.EDC;
using Catastrophe.BasePC.UI.DbDal;
using Catastrophe.BasePC.UI.DbDal;
using Catastrophe.BasePC.UI.File;
using Catastrophe.BasePC.UI.Model;
using Catastrophe.BasePC.UI.SystemIni;
using Catastrophe.Common.ObjM;
using Catastrophe.Common.SoftLicensing;
using Catastrophe.Initialize;
using Catastrophe.Initialize.IOCProvier;
using Catastrophe.Log;
using Microsoft.AspNetCore.SignalR.Protocol;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Org.BouncyCastle.Math.EC.ECCurve;

namespace Catastrophe.BasePC.UI.SystemIni
{
    /// <summary>
    /// 初始化
    /// </summary>
    public  class CatastropheIni
    {
        /// <summary>
        /// 消息抛出
        /// </summary>
        public event Action<string> meeage;
        /// <summary>
        /// 异常信息
        /// </summary>
        public event Action<string> erroMeeage;

        /// <summary>
        /// 异常信息
        /// </summary>
        private string erroMessage {  get; set; }
        /// <summary>
        /// 全部初始化
        /// </summary>
        public  void AllIni()
        {
            erroMessage = "";
            CatastropheInitializer.CatastropheBaseWfAssemblyName = typeof(CatastropheIni).Assembly.GetName().Name;
            FrameEnvironment.FrameVisualStyle = FileConfigIni.GetFileConfig.FrameVisualStyle;
            var value = EnDeCode.GetStrSplit<string>(FileConfigIni.GetFileConfig.ModuleIniNameSpace, ";");
            if (value.Item1)
            {
                FileConfigIni.GetFileConfig.ModuleIniNameSpaceSplit = value.Item2;
                CatastropheInitializer.AssemblyStrModuleAry = FileConfigIni.GetFileConfig.ModuleIniNameSpaceSplit;
            }

            LogSession.SoftId = FileConfigIni.GetFileConfig.SoftId;
            CatastropheInitializer.FrameAssemblyLoad();
            ContainerIni();
            Task task = Task.Run(new Action(CheckLicense));
            Task task2 = Task.Run(new Action(SysInitialize));
            Task task3 = Task.Run(new Action(LoadData));
            Task.WhenAll(task, task2, task3).GetAwaiter().OnCompleted(new Action(AllTaskFinished));
           
        }
        private  void LoadData()
        {
            Stopwatch watch = new Stopwatch();
            //Ggo<List<SysMenuEntity>>.GetObj = (from x in new SysMenuDal().QueryBaseMenuNode(FrameEnvironment.UserName, FrameEnvironment.UserNo, FrameEnvironment.Depart, FrameEnvironment.Identify, FrameEnvironment.AuthorizeType, FrameEnvironment.IsAdmin)
            //                                   orderby x.BaseIndex
            //                                   select x).ToList();
            Dictionary<string, List<IUserAuthorityTemplate>> assemblyInstance = CatastropheInitializer.GetAssemblyInstance<IUserAuthorityTemplate>();
            //Dictionary<string, object> dictionary = new SysAuthorityTemplateDal().UserAuthorityLoad(assemblyInstance, Ggo<SysUserEntity>.GetObj.UserName, Ggo<SysUserEntity>.GetObj.UserNo);
            //if (dictionary != null)
            //{
            //    Ggo.AddDicAry(dictionary);
            //}
           // this.CalLoadTime("load sys data", watchStart: true, watch);
        }
        private  void SysInitialize()
        {
            FrameEnvironment.IsDevMode = DevModeCheck();
            if (!FrameEnvironment.IsDevMode)
            {
                CatastropheInitializer.RemoveDevAssembly("Peanut.DevAuto.Wf");
            }
            FrameIni<IFileIni>("file config");
            FrameIni<IDbIni>("db config");
            FrameIni<ICommIni>("comm config");
            FrameIni<ICommTaskIni>("comm task");
            FrameIni<IControlTaskIni>("scheduler task");
            FrameIni<IServiceIni>("services");
            FrameIni<IAuthorizeIni>("authorize config");
        }
        private  void FrameIni<T>(string moduleName) where T : IRunManager
        {
            if (moduleName == null)
            {
                throw new ArgumentNullException("moduleName");
            }
            //if (this.LoadState == PreloadStateEnum.Fatal)
            //{
            //    return;
            //}
            //this.LoadTip(isError: false, "start loading " + moduleName + "...");
            StringBuilder stringBuilder = new StringBuilder();
            try
            {
                foreach (string item in CatastropheInitializer.AssemblyStrAry)
                {
                    BaseResponse<T> byKey = CatastropheProvider.GetByKey<T>(item);
                    if (!byKey.Success || byKey.Content == null)
                    {
                        continue;
                    }
                    ContainerBuilder containerBuilder = new ContainerBuilder();
                    string fullName = byKey.Content.GetType().FullName;
                    IFileIni fileIni = byKey.Content as IFileIni;
                    if (fileIni != null)
                    {
                        containerBuilder.RegisterInstance(fileIni).As<IFileIni>().Named<IFileIni>(fullName);
                        fileIni.FileLoad();
                    }
                    else
                    {
                        IDbIni dbIni = byKey.Content as IDbIni;
                        if (dbIni != null)
                        {
                            containerBuilder.RegisterInstance(dbIni).As<IDbIni>().Named<IDbIni>(fullName);
                            dbIni.DbLoad();
                        }
                        else
                        {
                            ICommIni commIni = byKey.Content as ICommIni;
                            if (commIni != null)
                            {
                                containerBuilder.RegisterInstance(commIni).As<ICommIni>().Named<ICommIni>(fullName);
                                commIni.CommLoad();
                            }
                            else
                            {
                                ICommTaskIni commTaskIni = byKey.Content as ICommTaskIni;
                                if (commTaskIni != null)
                                {
                                    containerBuilder.RegisterInstance(commTaskIni).As<ICommTaskIni>().Named<ICommTaskIni>(fullName);
                                    commTaskIni.CommTaskLoad();
                                }
                                else
                                {
                                    IControlTaskIni controlTaskIni = byKey.Content as IControlTaskIni;
                                    if (controlTaskIni != null)
                                    {
                                        containerBuilder.RegisterInstance(controlTaskIni).As<IControlTaskIni>().Named<IControlTaskIni>(fullName);
                                        controlTaskIni.ControlTaskLoad();
                                    }
                                    else
                                    {
                                        IAuthorizeIni authorizeIni = byKey.Content as IAuthorizeIni;
                                        if (authorizeIni != null)
                                        {
                                            containerBuilder.RegisterInstance(authorizeIni).As<IAuthorizeIni>().Named<IAuthorizeIni>(fullName);
                                            authorizeIni.AuthorizeLoad();
                                        }
                                        else
                                        {
                                            IServiceIni serviceIni = byKey.Content as IServiceIni;
                                            if (serviceIni != null)
                                            {
                                                containerBuilder.RegisterInstance(serviceIni).As<IServiceIni>().Named<IServiceIni>(fullName);
                                                serviceIni.ServiceLoad();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    CatastropheProvider<T>.Register(containerBuilder.Build());
                    CatastropheInitializer.AddIRunManager(item, byKey.Content);
                }
                //this.LoadTip(isError: false, "load " + moduleName + " completed!");
                //this.CalLoadTime(moduleName);
            }
            catch (Exception ex)
            {
               // this.ThrowException(ex, "load " + moduleName + " failed!");
            }
        }
        private static bool DevModeCheck()
        {
            if (FileConfigIni.GetFileConfig.DevMode == "IsAttached")
            {
                return FrameEnvironment.IsDebug;
            }
            if (FileConfigIni.GetFileConfig.DevMode == "MachineInfo")
            {
                string text = Environment.MachineName.ToUpper();
                string userName = Environment.UserName;
                string text2 = text + "|" + userName;
                List<string> list = (from x in FileConfigIni.GetFileConfig.MachineUserName?.Split('}')
                                     where x != ""
                                     select x).ToList();
                if (list != null)
                {
                    foreach (string item in list)
                    {
                        string text3 = item.Trim();
                        if (!(text3 == "") && text3.StartsWith("{"))
                        {
                            string text4 = text3.Remove(0, 1);
                            List<string> list2 = (from x in text4.Split('|')
                                                  where x.Trim() != ""
                                                  select x).ToList();
                            if (list2.Count == 2 && (list2[0].ToUpper() + "|" + list2[1]).Equals(text2.Replace(" ", "")))
                            {
                                return true;
                            }
                        }
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 全部任务结束
        /// </summary>
        private  void AllTaskFinished()
        {
            
            //if (this.LoadState == PreloadStateEnum.Fatal || this.LoadState == PreloadStateEnum.Error)
            //{
            //    string text = this._sberError.ToString();
            //    return;
            //}
            //while (this.MainFrm == null)
            //{
            //    Thread.Sleep(5);
            //}
            //try
            //{
            //    this.WatchReset();
            //    this.LoadTip(isError: false, "gui 初始化...");
            //    this.MainTdRun(delegate
            //    {
            //        this.MainFrm.Visible = false;
            //        MainFormC1 mainForm = this.MainFrm as MainFormC1;
            //        if (mainForm != null)
            //        {
            //            List<IFrameBottom> assemblyInstanceList = PeanutInitializer.GetAssemblyInstanceList<IFrameBottom>();
            //            if (assemblyInstanceList.Count > 0)
            //            {
            //                ContainerBuilder containerBuilder = new ContainerBuilder();
            //                foreach (IFrameBottom item2 in assemblyInstanceList)
            //                {
            //                    UserControl userControl = item2 as UserControl;
            //                    if (userControl != null)
            //                    {
            //                        mainForm.BottomExtend(userControl);
            //                        item2.LoadBottom((Panel)userControl.Parent);
            //                        containerBuilder.RegisterInstance(userControl).As<IFrameBottom>();
            //                    }
            //                }
            //                PeanutProvider<IFrameBottom>.Register(containerBuilder.Build());
            //            }
            //            mainForm.LoadControl();
            //        }
            //    });
            //    this.CalLoadTime("main ui initialize", watchStart: false);
            //    this._watch2.Stop();
            //    FrameEnvironment.SysLoadDetails = this._sberLoadLog.ToString();
            //    FrameEnvironment.TimeConsume = this._watch2.ElapsedMilliseconds;
            this.IniFinished();
            OutMessage("初始化完成");
            //}
            //catch (Exception ex)
            //{
            //    string item = ExceptionUtil.ExceptionFormat(ex).Item1;
            //    this.LoadTip(isError: true, item);
            //}
        }
        private void IniFinished()
        {
            CatastropheInitializer.FrameLoadFinishedHandler?.Invoke(new object[4]
            {
                FrameEnvironment.UserName,
                FrameEnvironment.UserNo,
                FrameEnvironment.Identify,
                FrameEnvironment.IsAdmin
            });
        }
        private static void CheckLicense()
        {
            //bool debug = true;
            //if (this._licenseCheck == null)
            //{
            //    Stopwatch watch = new Stopwatch();
            //    this.WatchReset(watch);
            //    string localPwd = EnDeCode.CreateDefaultLicensePwd();
            //    this._licenseCheck = new LicenseCheck(localPwd, (string x) => EnDeCode.CreateDefaultLicensePwd(x));
            //    this._licenseCheck.LicTipHandler = FrameEnvironment.LicTipHandler;
            //    LicCheckRet licCheckRet = this._licenseCheck.SoftLicense();
            //    long num = this.CalLoadTime("lic check", watchStart: true, watch);
            //    if (debug)
            //    {
            //        FrameEnvironment.IsLicenseValid = true;
            //        FrameEnvironment.PubKey = licCheckRet.PubKey;
            //    }
            //    else
            //    {
            //        if (!licCheckRet.Success)
            //        {
            //            this.BuildSerialNo();
            //            this.ThrowException(licCheckRet.Message);
            //        }
            //        else
            //        {
            //            FrameEnvironment.IsLicenseValid = true;
            //            FrameEnvironment.PubKey = licCheckRet.PubKey;
            //        }
            //    }

            //}
        }
        /// <summary>
        /// 
        /// </summary>
        public  void ContainerIni()
        {
            try
            {
                OutMessage("start loading ioc container...");
                CatastropheInitializer.ExcuteContainerIni();
                OutMessage("load ioc container completed！");
                OutMessage("ioc init");
            }
            catch (Exception ex)
            {
                OutErroMessage("初始化IOC失败!");
            }
        }

        private void OutMessage(string str)
        {
            meeage?.Invoke(str);
        }
        private void OutErroMessage(string str)
        {
            erroMessage += str;
            erroMeeage?.Invoke(erroMessage);
        }
    }
}
